package cn.hfjava.kz.config;

import cn.dev33.satoken.interceptor.SaInterceptor;
import cn.dev33.satoken.stp.StpUtil;
import cn.hfjava.kz.config.properties.KzUploadProperties;
import cn.hfjava.kz.config.properties.MdUploadProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import jakarta.annotation.Resource;
import org.modelmapper.ModelMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.ArrayList;
import java.util.List;

/**
 * 应用程序配置类，配置静态资源处理、拦截器和跨域设置
 */
@Configuration
public class AppConfig implements WebMvcConfigurer {
    @Bean
    public ModelMapper modelMapper() {
        return new ModelMapper();
    }
    @Resource
    private KzUploadProperties kzUploadProperties;
    @Resource
    private MdUploadProperties mdUploadProperties;

    /**
     * 配置静态资源处理器，设置上传文件保存目录
     *
     * @param registry 资源处理器注册表
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        // 将指定的URL路径映射到文件系统中的目录
        registry.addResourceHandler(kzUploadProperties.getAssetsUrl())
                .addResourceLocations("file:" + kzUploadProperties.getUploadPath());
        registry.addResourceHandler(mdUploadProperties.getAssetsUrl())
                .addResourceLocations("file:" + mdUploadProperties.getUploadPath());
    }

    /**
     * 配置拦截器
     *
     * @param registry 拦截器注册表
     */
//    @Override
//    public void addInterceptors(InterceptorRegistry registry) {
//        List<String> path = new ArrayList<>();
//        path.add("/api/v1/auth/login");
//        path.add("/api/v1/auth/sendCode");
//        // 注册 Sa-Token 拦截器，校验所有以 /api/v1/ 开头的请求是否登录，除了登录接口
//        registry.addInterceptor(new SaInterceptor(handle -> StpUtil.checkLogin()))
//                .addPathPatterns("/api/v1/**")
//
//                .excludePathPatterns(path);
//        //.excludePathPatterns("/api/v1/auth/register");
//    }

//    /**
//     * 全局配置跨域
//     *
//     * @param registry 跨域注册表
//     */
//    @Override
//    public void addCorsMappings(CorsRegistry registry) {
//        // 配置允许跨域访问的路径和设置
//        registry.addMapping("/api/v1/**") // 允许以 /api/v1/ 开头的所有请求路径跨域访问
//                .allowedOriginPatterns("*") // 允许所有域名进行跨域访问
//                .allowedOrigins("http://localhost:5173")
//                .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") // 允许的请求方法
//                .allowedHeaders("*") // 允许的请求头
//                .maxAge(3600L) // 预检请求的有效期，单位为秒
//                .allowCredentials(true) // 是否允许携带Cookie
//                .exposedHeaders("*"); // 允许暴露的响应头 }

    // 注册拦截器
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 基于 StpUtil.checkLogin() 的登录校验拦截器，并且排除了/api/user/login接口用来开放登录（除了/api/user/login以外的所有接口都需要登录才能访问）。
        registry.addInterceptor(new SaInterceptor(handle -> StpUtil.checkLogin()))
                .addPathPatterns("/api/**")
                .excludePathPatterns(

                        "/api/v1/auth/login",
                        "/api/v1/auth/sendCode",
//                        "/api/v1/auth/list",
                        "/api/v1/auth/checkCode",
                        "/v3/api-docs/**",
                        "/swagger-resources/**",
                        "/webjars/**",
                        "/swagger-ui/index.html",
                        "/favicon.ico");
    }



    // 解决跨域
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOriginPatterns("*")
                .allowedMethods("GET", "POST", "PUT", "DELETE","OPTIONS")
                .allowedHeaders("*")
                .allowCredentials(true)
                .maxAge(3600)
                .exposedHeaders("Authorization");
    }


    //后端接口返回的json数据含有null的不会在前端显示
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
        //后端接口返回的json数据中含有null的,则不在前端展示
        builder.serializationInclusion(JsonInclude.Include.NON_NULL);
        //添加jackson消息转换器
        converters.add(new MappingJackson2HttpMessageConverter(builder.build()));
    }

}
